package com.sofa.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Date;
import java.util.Map;

/**
 * JWT令牌生成和校验工具类
 * ai辅助编写
 */
public class JwtUtil {

    /**
     * 生成 JWT
     * @param secretKey JWT秘钥（长度不足时会自动扩展）
     * @param ttlMillis 过期时间（毫秒）
     * @param claims 自定义声明信息
     * @return 生成的 JWT 字符串
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // jwt要求秘钥长度至少为256bit,这里自动扩展密钥长度（SHA-256 处理）
        SecretKey key = generateSecureKey(secretKey);

        // 设置过期时间
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

        // 构建 JWT
        JwtBuilder builder = Jwts.builder()
                .setClaims(claims) // 设置自定义声明
                .signWith(key, SignatureAlgorithm.HS256) // 使用密钥签名
                .setExpiration(exp); // 设置过期时间

        return builder.compact();
    }

    /**
     * 解析 JWT
     * @param secretKey JWT秘钥（长度不足时会自动扩展）
     * @param token 需要解析的 JWT
     * @return JWT 的 Claims 信息
     */
    public static Claims parseJWT(String secretKey, String token) {
        // 自动扩展密钥长度（SHA-256 处理）
        SecretKey key = generateSecureKey(secretKey);

        return Jwts.parserBuilder()
                .setSigningKey(key) // 设置签名密钥
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 自动扩展密钥长度，使其符合 JWT 256-bit 要求
     * @param shortSecretKey 原始密钥（可能不足）
     * @return 32 字节安全密钥
     */
    private static SecretKey generateSecureKey(String shortSecretKey) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hashedKey = digest.digest(shortSecretKey.getBytes(StandardCharsets.UTF_8));
            return Keys.hmacShaKeyFor(hashedKey); // 生成符合安全要求的 256-bit 密钥
        } catch (Exception e) {
            throw new RuntimeException("密钥扩展失败", e);
        }
    }
}


